package com.wjc.basemodule.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.util.forEach
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.wjc.basemodule.R
import com.wjc.basemodule.BR
import com.wjc.basemodule.utils.LogTools
import com.wjc.basemodule.widget.DialogManager
import com.wjc.basemodule.widget.DialogManagerKt

abstract class BaseFragment<DB : ViewDataBinding> : Fragment() {
    private val TAG = "BaseFragment"
    var defaultPage: DefaultPage? = null
    protected var mActivity: AppCompatActivity? = null
    protected var mAnimationLoaded = false
    private var mFragmentProvider: ViewModelProvider? = null
    private var mActivityProvider: ViewModelProvider? = null
    private var networkErrorOrNoDataView: View? = null
    private var progressBar: ProgressBar? = null
    protected lateinit var binding: DB

    protected abstract val dataBindingConfig: DataBindingConfig


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        context?.let { DialogManagerKt() }?.let { lifecycle.addObserver(it) }
        lifecycle.addObserver(DialogManagerKt(this.javaClass.simpleName))
        initViewModel()
        LogTools.i(TAG, ":onCreate ")
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, dataBindingConfig.layout, container, false)
        binding.lifecycleOwner = this
        if (dataBindingConfig.stateViewModel != null) {
            binding.setVariable(BR.vm, dataBindingConfig.stateViewModel)
        }
        dataBindingConfig.bindingParams.forEach { index, param -> binding.setVariable(index, param) }

        val loadingView = binding.root.findViewById<View>(R.id.loading_progress)
        val defaultView = binding.root.findViewById<View>(R.id.vs_error_or_no_data_container)
        if (loadingView != null || defaultView != null) {
            defaultPage = DefaultPage(loadingView, if (defaultView is ViewStub) defaultView else null)
        }
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //observe一定要在初始化最后，因为observe会收到黏性事件，随后对ui做处理
        observe()
    }

    /**
     * 初始化viewModel
     * 之所以没有设计为抽象，是因为部分简单页面可能不需要viewModel
     * observe同理
     */
    open fun initViewModel() {

    }

    /**
     * 注册观察者
     */
    open fun observe() {

    }

    /**
     * 通过activity获取viewModel，跟随activity生命周期
     */
    protected fun <T : ViewModel?> getActivityViewModel(modelClass: Class<T>): T {
        if (mActivityProvider == null) {
            mActivityProvider = ViewModelProvider(mActivity!!)
        }
        return mActivityProvider!!.get(modelClass)
    }

    /**
     * 通过fragment获取viewModel，跟随fragment生命周期
     */
    protected open fun <T : ViewModel?> getFragmentViewModel(modelClass: Class<T>): T {
        if (mFragmentProvider == null) {
            mFragmentProvider = ViewModelProvider(this)
        }
        return mFragmentProvider!!.get(modelClass)
    }

    /**
     * fragment跳转
     */
    protected fun nav(): NavController {
        return NavHostFragment.findNavController(this)
    }


    protected val dialogManager: DialogManager
        get() = baseActivity.dialogManager


    val baseActivity: BaseActivity<*>
        get() = activity as BaseActivity<*>


    override fun onDestroyView() {
        super.onDestroyView()
        binding.unbind()
    }
}